package cn.qianxun.meta.user.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.lang.tree.Tree;
import cn.qianxun.meta.common.core.dto.RowsData;
import cn.qianxun.meta.common.core.utils.PasswordGenerator;
import cn.qianxun.meta.common.core.utils.StreamUtils;
import cn.qianxun.meta.common.core.web.dto.SelectLongDTO;
import cn.qianxun.meta.common.core.web.dto.SelectVO;
import cn.qianxun.meta.common.core.web.vo.RemoveLongDTO;
import cn.qianxun.meta.common.log.annotation.Log;
import cn.qianxun.meta.common.log.enums.BusinessType;
import cn.qianxun.meta.user.dto.*;
import cn.qianxun.meta.user.entity.SysUser;
import cn.qianxun.meta.user.service.ISysUserService;
import cn.qianxun.meta.user.vo.SysUserDetailsVO;
import cn.qianxun.meta.user.vo.SysUserListVO;
import cn.qianxun.meta.common.core.domain.Result;
import cn.qianxun.meta.common.satoken.utils.LoginHelper;
import cn.qianxun.meta.dept.entity.SysDept;
import cn.qianxun.meta.dept.service.ISysDeptService;
import cn.qianxun.meta.menu.vo.RouterVO;
import cn.qianxun.meta.role.entity.SysRole;
import cn.qianxun.meta.role.service.ISysRoleService;
import cn.qianxun.meta.user.dto.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户信息表 前端控制器
 * </p>
 *
 * @author fuzhilin
 * @since 2023-08-21 02:16:24
 */
@RequiredArgsConstructor
@Validated
@RestController
@Tag(name = "用户信息管理", description = "用户信息管理")
@RequestMapping("/web/v1/sysUser")
public class SysUserController {


    private final ISysUserService sysUserService;
    private final ISysRoleService sysRoleService;
    private final ISysDeptService sysDeptService;


    @SaCheckPermission("web:v1:sysUser:list")
    @PostMapping("/list")
    @Log(title = "获取用户列表", businessType = BusinessType.SELECT)
    @Operation(summary = "获取用户列表", description = "获取用户列表")
    public Result<RowsData<SysUserListVO>> selectUserList(@RequestBody SysUserQueryDTO dto) {
        return Result.success("查询成功", sysUserService.selectUserList(dto));
    }

    @SaCheckPermission("web:v1:sysUser:add")
    @Log(title = "新增用户", businessType = BusinessType.INSERT)
    @Operation(summary = "新增用户", description = "新增用户")
    @PostMapping("/addUser")
    public Result<Object> addUser(@Validated @RequestBody AddSysUserDTO dto) {
        sysUserService.addUser(dto);
        return Result.success("添加成功！");
    }

    @SaCheckPermission("web:v1:sysUser:edit")
    @Log(title = "编辑用户", businessType = BusinessType.UPDATE)
    @PostMapping("/editUser")
    @Operation(summary = "编辑用户", description = "编辑用户")
    public Result<Object> editUser(@Validated @RequestBody AddSysUserDTO dto) {
        sysUserService.editUser(dto);
        return Result.success("修改成功！");
    }

    @SaCheckPermission("web:v1:sysUser:remove")
    @Log(title = "删除用户", businessType = BusinessType.DELETE)
    @Operation(summary = "删除用户", description = "删除用户")
    @PostMapping("/remove")
    public Result<Object> deleteUserByIds(@RequestBody @Validated RemoveLongDTO dto) {
        sysUserService.deleteUserByIds(dto);
        return Result.success("删除成功！");
    }

    @PostMapping("/details")
    @SaCheckPermission("web:v1:sysUser:details")
    @Operation(summary = "获取用户信息", description = "获取用户信息")
    public Result<SysUserDetailsVO> details(@RequestBody SelectLongDTO selectLongDTO) {
        return Result.success(sysUserService.details(selectLongDTO.getIdLong()));
    }


    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public Result<Map<String, Object>> getInfo() {
        return Result.success(sysUserService.getInfo());
    }

    /**
     * 根据模块获取路由信息
     *
     * @return
     */
    @GetMapping("/getRouters")
    public Result<List<RouterVO>> getRoutersByModular() {
        return Result.success("查询成功", sysUserService.getRouter());
    }

    /**
     * 重置密码
     */
    @SaCheckPermission("web:v1:sysUser:resetPwd")
    @Log(title = "重置密码", businessType = BusinessType.UPDATE)
    @PostMapping("/resetPwd")
    public Result<Object> resetPwd(@RequestBody SysUserPasswordDTO user) {
        SysUser tmpUser = new SysUser();
        tmpUser.setUserId(user.getUserId());
        sysUserService.checkUserAllowed(tmpUser);
        sysUserService.checkUserDataScope(user.getUserId());
        user.setPassword(BCrypt.hashpw(user.getPassword()));
        return Result.success(sysUserService.resetPwd(user));
    }

    @Log(title = "自动生成密码", businessType = BusinessType.OTHER)
    @PostMapping("/createPwd")
    public Result<Object> createPwd() {
        return Result.success("生成密码成功", new PasswordGenerator(10, 4).generateRandomPassword());
    }


    /**
     * 状态修改
     */
    @SaCheckPermission("web:v1:sysUser:changeStatus")
    @Log(title = "状态修改", businessType = BusinessType.UPDATE)
    @PostMapping("/changeStatus")
    public Result<Object> changeStatus(@RequestBody SysUser user) {
        sysUserService.checkUserAllowed(user);
        sysUserService.checkUserDataScope(user.getUserId());
        return Result.success(sysUserService.updateUserStatus(user));
    }

    /**
     * 根据用户编号获取授权角色
     *
     * @param selectLongDTO 用户ID
     */
    //@SaCheckPermission("web:v1:sysUser:authRole")
    @PostMapping("/authRoleByUserId")
    public Result<Map<String, Object>> authRole(@RequestBody SelectLongDTO selectLongDTO) {
        Map<String, Object> ajax = new HashMap<>();
        SysUser user = sysUserService.getById(selectLongDTO.getIdLong());
        List<SysRole> roles = sysRoleService.selectRolesByUserId(selectLongDTO.getIdLong());
        ajax.put("user", user);
        ajax.put("roles", LoginHelper.isAdmin(selectLongDTO.getIdLong()) ? roles : StreamUtils.filter(roles, r -> !r.isAdmin()));
        return Result.success(ajax);
    }

    /**
     * 用户授权角色
     * d
     *
     * @param userId  用户Id
     * @param roleIds 角色ID串
     */
    // @SaCheckPermission("web:v1:sysUser:authRole")
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PutMapping("/authRole")
    public Result<Object> insertAuthRole(Long userId, Long[] roleIds) {
        sysUserService.checkUserDataScope(userId);
        sysUserService.insertUserAuth(userId, roleIds);
        return Result.success("操作成功");
    }

    /**
     * 获取部门树列表
     */
    @SaCheckPermission("web:v1:sysUser:deptTree")
    @GetMapping("/deptTree")
    public Result<List<Tree<Long>>> deptTree(SysDept dept) {
        return Result.success(sysDeptService.selectDeptTreeList(dept));
    }

    /**
     * 流程 用户下拉选(不分页)
     *
     * @param dto dto
     * @return List<SelectVO>
     */
    //@SaCheckPermission("web:v1:sysUser:getProcessUserList")
    @PostMapping("/getProcessUserList")
    public Result<List<SelectVO>> getProcessUserList(@RequestBody UserDeptRoleSelectDTO dto) {
        return Result.success("查询成功", sysUserService.getProcessUserList(dto));
    }

    /**
     * 流程 用户下拉选(分页)
     *
     * @param dto dto
     * @return RowsData<SelectVO>
     */
    //@SaCheckPermission("web:v1:sysUser:getProcessUserPageList")
    @PostMapping("/getProcessUserPageList")
    public Result<RowsData<SelectVO>> getProcessUserPageList(@RequestBody UserDeptRoleSelectDTO dto) {
        return Result.success("查询成功", sysUserService.getProcessUserPageList(dto));
    }


    /**
     * 修改密码
     *
     * @param sysUserEditPasswordDTO 密码
     */
    @Log(title = "修改密码", businessType = BusinessType.UPDATE)
    @PostMapping("/updatePwd")
    public Result<Boolean> updatePwd(@RequestBody SysUserEditPasswordDTO sysUserEditPasswordDTO) {
        return Result.success(sysUserService.updatePwd(sysUserEditPasswordDTO));
    }

    /**
     * 头像上传
     *
     * @param sysUserEditAvatarDTO 用户头像
     */
    @Log(title = "修改个人信息", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/updateUserInfoSelf")
    public Result<Boolean> updateUserInfoSelf(@Validated @RequestBody SysUserEditAvatarDTO sysUserEditAvatarDTO) {
        return Result.success(sysUserService.updateUserInfoSelf(sysUserEditAvatarDTO));
    }

    /**
     * 获取用户邮箱
     *
     * @return List<SelectVO>
     */
    @GetMapping("/getUserEmil")
    public Result<List<SelectVO>> getUserEmil() {
        return Result.success("查询成功", sysUserService.getUserEmil());
    }
}
